using DataAnalyticsTools.Core;
using DataAnalyticsTools.Models;
using GrapeCity.Forguncy.Commands;
using GrapeCity.Forguncy.Log;
using GrapeCity.Forguncy.Plugin;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks;

namespace DataAnalyticsTools
{
    [Icon("pack://application:,,,/DataAnalyticsTools;component/Resources/Icon.png")]
    [Designer("DataAnalyticsTools.Designer.DataAnalyticsToolsServerCommandDesigner, DataAnalyticsTools")]
    [Category("数据分析")]
    [OrderWeight(50)]
    public class TrendBySeasonalDecomposition : Command, ICommandExecutableInServerSideAsync, IServerCommandParamGenerator
    {
        [FormulaProperty]
        [DisplayName("时间序列数据（单变量）")]
        [Description("float[]数组，每个样本的值。")]
        public object featuresExpr { get; set; }

        [FormulaProperty]
        [DisplayName("分解周期")]
        [Description("周期长度，如按月分解，用12；按季度分解用4。")]
        public object periodExpr { get; set; } = 4;

        [DisplayName("分解方法")]
        public DecomposeMethod Method { get; set; }

        [ResultToProperty]
        [DisplayName("保存趋势到变量")]
        [Description("季节性趋势序列在SeasonalComponents属性，去除季节影响后的趋势序列在TrendComponents。")]
        public string ResultTo { get; set; } = "分解后的特征趋势";

        public async Task<ExecuteResult> ExecuteAsync(IServerCommandExecuteContext dataContext)
        {
            var features = GeneralConvertors.ConvertToFloatArray(await dataContext.EvaluateFormulaAsync(featuresExpr));
            var period = int.Parse((await dataContext.EvaluateFormulaAsync(periodExpr))?.ToString() ?? "3");

            var rawResults = SeasonalAnalyzer.SeasonalTrendDecomposition(features, period, Method);
            dataContext.Parameters[ResultTo] = rawResults;

            return new ExecuteResult();
        }

        public override string ToString()
        {
            if (featuresExpr == null)
            {
                return "季节性趋势分解";
            }
            else
            {
                return "季节性趋势分解（" + Method + "法）：" + ResultTo;
            }
        }

        public override CommandScope GetCommandScope()
        {
            return CommandScope.ExecutableInServer;
        }

        public IEnumerable<GenerateParam> GetGenerateParams()
        {

            List<GenerateParam> result = [];

            result.Add(new GenerateObjectParam()
            {
                ParamName = this.ResultTo,
                Description = "分解后趋势的结果",
                ParamScope = CommandScope.All,
                SubPropertiesDescription = new Dictionary<string, string>() {
                    { "TrendComponents","去除季节影响的趋势数组"},
                    { "SeasonalComponents","季节性趋势数组" }
                }
            });


            return result;
        }

    }

}
